package cn.iocoder.yudao.module.infra.service.ocr;

import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.Set;
import java.util.concurrent.atomic.AtomicLong;

/**
 * OCR 配置缓存性能监控
 * 
 * @author 芋道源码
 */
@Component
@Slf4j
public class OcrConfigCacheMonitor {

    @Resource
    private RedisTemplate<String, Object> redisTemplate;

    // 缓存命中统计
    private final AtomicLong cacheHitCount = new AtomicLong(0);
    private final AtomicLong cacheMissCount = new AtomicLong(0);
    private final AtomicLong totalRequests = new AtomicLong(0);

    // OCR配置缓存key前缀
    private static final String OCR_CONFIG_CACHE_KEY = "ocr_config:type_status:";

    /**
     * 记录缓存命中
     */
    public void recordCacheHit() {
        cacheHitCount.incrementAndGet();
        totalRequests.incrementAndGet();
    }

    /**
     * 记录缓存未命中
     */
    public void recordCacheMiss() {
        cacheMissCount.incrementAndGet();
        totalRequests.incrementAndGet();
    }

    /**
     * 获取缓存命中率
     */
    public double getCacheHitRate() {
        long total = totalRequests.get();
        if (total == 0) {
            return 0.0;
        }
        return (double) cacheHitCount.get() / total;
    }

    /**
     * 定期统计缓存性能（每10分钟）
     */
    @Scheduled(fixedRate = 600000) // 10分钟
    public void logCacheStatistics() {
        long total = totalRequests.get();
        long hits = cacheHitCount.get();
        long misses = cacheMissCount.get();
        
        if (total > 0) {
            double hitRate = (double) hits / total * 100;
            log.info("OCR配置缓存性能统计 - 总请求: {}, 命中: {}, 未命中: {}, 命中率: {:.2f}%", 
                    total, hits, misses, hitRate);
            
            // 如果命中率低于80%，发出警告
            if (hitRate < 80.0) {
                log.warn("OCR配置缓存命中率较低: {:.2f}%，建议检查缓存配置", hitRate);
            }
        }
    }

    /**
     * 定期清理过期的缓存key（每小时）
     */
    @Scheduled(fixedRate = 3600000) // 1小时
    public void cleanupExpiredCache() {
        try {
            Set<String> keys = redisTemplate.keys(OCR_CONFIG_CACHE_KEY + "*");
            if (keys != null && !keys.isEmpty()) {
                log.debug("检查到 {} 个OCR配置缓存key", keys.size());
                // Redis会自动清理过期key，这里只是统计
            }
        } catch (Exception e) {
            log.warn("清理OCR配置缓存时发生异常", e);
        }
    }

    /**
     * 重置统计计数器
     */
    public void resetStatistics() {
        cacheHitCount.set(0);
        cacheMissCount.set(0);
        totalRequests.set(0);
        log.info("OCR配置缓存统计计数器已重置");
    }

    /**
     * 获取当前缓存统计信息
     */
    public CacheStatistics getStatistics() {
        return new CacheStatistics(
                totalRequests.get(),
                cacheHitCount.get(),
                cacheMissCount.get(),
                getCacheHitRate()
        );
    }

    /**
     * 缓存统计信息DTO
     */
    public static class CacheStatistics {
        private final long totalRequests;
        private final long cacheHits;
        private final long cacheMisses;
        private final double hitRate;

        public CacheStatistics(long totalRequests, long cacheHits, long cacheMisses, double hitRate) {
            this.totalRequests = totalRequests;
            this.cacheHits = cacheHits;
            this.cacheMisses = cacheMisses;
            this.hitRate = hitRate;
        }

        public long getTotalRequests() { return totalRequests; }
        public long getCacheHits() { return cacheHits; }
        public long getCacheMisses() { return cacheMisses; }
        public double getHitRate() { return hitRate; }

        @Override
        public String toString() {
            return String.format("CacheStatistics{totalRequests=%d, cacheHits=%d, cacheMisses=%d, hitRate=%.2f%%}", 
                    totalRequests, cacheHits, cacheMisses, hitRate * 100);
        }
    }
}